#ifndef __LINDENI_GPIO__
#define __LINDENI_GPIO__

#ifdef __cplusplus
extern "C" {
#endif

#include <sys/mman.h>
#include <sys/ioctl.h>
#include <fcntl.h>
#include <pthread.h>

/* pin group base number name space,
 * the max pin number : 26*32=832.
 */
#define SUNXI_PA_BASE   0
#define SUNXI_PB_BASE   32
#define SUNXI_PC_BASE   64
#define SUNXI_PD_BASE   96
#define SUNXI_PE_BASE   128
#define SUNXI_PF_BASE   160
#define SUNXI_PG_BASE   192
#define SUNXI_PH_BASE   224
#define SUNXI_PI_BASE   256
#define SUNXI_PJ_BASE   288
#define SUNXI_PK_BASE   320
#define SUNXI_PL_BASE   352
#define SUNXI_PM_BASE   384
#define SUNXI_PN_BASE   416
#define SUNXI_PO_BASE   448

/* sunxi gpio name space */
#define PA(n)    (SUNXI_PA_BASE + (n))
#define PB(n)    (SUNXI_PB_BASE + (n))
#define PC(n)    (SUNXI_PC_BASE + (n))
#define PD(n)    (SUNXI_PD_BASE + (n))
#define PE(n)    (SUNXI_PE_BASE + (n))
#define PF(n)    (SUNXI_PF_BASE + (n))
#define PG(n)    (SUNXI_PG_BASE + (n))
#define PH(n)    (SUNXI_PH_BASE + (n))
#define PI(n)    (SUNXI_PI_BASE + (n))
#define PJ(n)    (SUNXI_PJ_BASE + (n))
#define PK(n)    (SUNXI_PK_BASE + (n))
#define PL(n)    (SUNXI_PL_BASE + (n))
#define PM(n)    (SUNXI_PM_BASE + (n))
#define PN(n)    (SUNXI_PN_BASE + (n))
#define PO(n)    (SUNXI_PO_BASE + (n))

enum GpioMode
{
	GPIO_MODE_INPUT		= 0,
	GPIO_MODE_OUTPUT	= 1,
};

enum GpioEdgeType
{
	INT_EDGE_NONE					= 0,
	INT_EDGE_FALLING				= 1,
	INT_EDGE_RISING					= 2,
	INT_EDGE_BOTH_RISING_FALLING	= 3,
};
/********************************************************************************
 * API: gpio_export
 * function: Require GPIO.
 * parameters:
 *     port: The port system index of GPIO.
 *           Must initialize by macro PA() to PO() defined above.
 * ret: 0:succeed; -1:failed
 ********************************************************************************/
int gpio_export(int port);

/********************************************************************************
 * API: gpio_unexport
 * function: Release GPIO.
 * parameters:
 *     port: The port system index of GPIO.
 *           Must initialize by macro PA() to PO() defined above.
 * ret: 0:succeed; -1:failed
 ********************************************************************************/
int gpio_unexport(int port);

/********************************************************************************
 * API: gpio_set_mode
 * function: Set up the GPIO mode(input or output).
 * parameters:
 *     port: The port system index of GPIO.
 *           Must initialize by macro PA() to PO() defined above.
 *     mode: The mode selected (GPIO_MODE_INPUT or GPIO_MODE_OUTPUT)
 * ret: 0:succeed; -1:failed
 ********************************************************************************/
int gpio_set_mode(int port, enum GpioMode mode);

/********************************************************************************
 * API:gpio_get_value
 * function: Read the value of GPIO under GPIO_MODE_INPUT.
 * parameters:
 *     port: The port system index of GPIO.
 *           Must initialize by macro PA() to PO() defined above.
 * ret: 0/1:succeed; -1:failed
 ********************************************************************************/
int gpio_get_value(int port);

/********************************************************************************
 * API:gpio_set_value
 * function: Write the value to GPIO under GPIO_MODE_OUTPUT.
 *     port: The port system index of GPIO.
 *           Must initialize by macro PA() to PO() defined above.
 * ret: 0:succeed; -1:failed
 ********************************************************************************/
int gpio_set_value(int port, int value);

/********************************************************************************
 * API:gpio_isr_register_cb
 * function: Register callback function to respond the GPIO interrupt.
 *     port: The port system index of GPIO.
 *           Must initialize by macro PA() to PO() defined above.
 *     type: The edge interrupt trigger type. Details see enum GpioEdgeType above.
 *     function: The pointer for registering callback function.
 *     args: The pointer for the callback funcition parameters.
 * ret: 0:succeed; -1:failed
 ********************************************************************************/
int gpio_isr_register_cb (int port, enum GpioEdgeType type, void *(*function)(void *), void *args);

/********************************************************************************
 * API:gpio_isr_start_cb
 * function: Create a thread to deal with the registered interrupt event.
 *     port: The port system index of GPIO.
 *           Must initialize by macro PA() to PO() defined above.
 * ret: 0:succeed; -1:failed
 ********************************************************************************/
int gpio_isr_start_cb (int port);

/********************************************************************************
 * API:gpio_isr_stop_cb
 * function: Destory the thread and clear all the registered information.
 *     port: The port system index of GPIO.
 *           Must initialize by macro PA() to PO() defined above.
 * ret: 0:succeed; -1:failed
 ********************************************************************************/
int gpio_isr_stop_cb (int port);

#ifdef __cplusplus
}
#endif

#endif
